package com.swf.jpa.framework.convert;

import java.beans.PropertyDescriptor;
import java.io.File;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.MethodParameter;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.swf.jpa.framework.constant.MockEnum;
import com.swf.jpa.generator.TableModel;
import com.swf.jpa.util.MockUtils;

/**
 * 参数转换
 *
 * @author gavin
 * @create 13-8-2
 * @since 1.0.0
 */
public class CommonArgumentResolver implements HandlerMethodArgumentResolver, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return ClassUtils.isAssignable(TableModel.class, parameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        //
        Class<?> targetClass = methodParameter.getParameterType();
        HttpServletRequest request = (HttpServletRequest)webRequest.getNativeRequest(HttpServletRequest.class);
        //
        return fillParam(targetClass, request);
    }

    private Object fillParam(Class<?> targetClass, HttpServletRequest request) {
        //
        BeanWrapper beanWrapper = new BeanWrapperImpl(targetClass);
        Map requestmap = (Map) MockUtils.getAttribute(request, MockEnum.FIELDS_REQUEST);
        for(PropertyDescriptor pd : beanWrapper.getPropertyDescriptors()) {
            //
            if(beanWrapper.isWritableProperty(pd.getName())) {
                //
                if(BeanUtils.isSimpleValueType(pd.getPropertyType())) {
                    // 将标准接口的参数名解析成第三方接口对应的参数名
                    String propertyName = pd.getName();
                    Object propertyValue ;
                    if (requestmap!=null&&requestmap.containsKey(propertyName)){
                    	propertyValue = requestmap.get(propertyName);
                    }else{
                    	propertyValue = request.getParameter(propertyName);
                    }
                    if(propertyValue!=null) {
                        beanWrapper.setPropertyValue(pd.getName(), propertyValue);
                    }
                } else if(BeanUtils.isSimpleProperty(pd.getPropertyType())==false) {
                	if (pd.getPropertyType()==File.class){
                		File propertyValue = MockUtils.getAttribute(request, MockEnum.FILE_UPLOAD,File.class);
                		if(propertyValue!=null) {
                			beanWrapper.setPropertyValue(pd.getName(), propertyValue);
                		}
                	}
                }
            }
        }
        //
        return beanWrapper.getWrappedInstance();
    }

}
